package com.kinroy.briefreport.service.serviceimpl;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinroy.briefreport.dto.*;
import com.kinroy.briefreport.entity.*;
import com.kinroy.briefreport.enums.note.NoteType;
import com.kinroy.briefreport.enums.task.TaskStatus;
import com.kinroy.briefreport.mapper.*;
import com.kinroy.briefreport.service.*;
import com.kinroy.briefreport.utils.VerificationCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private IHandOverNodeService nodeService;

    @Autowired
    private IRegisterService registerService;

    @Autowired
    private INoteService noteService;

    @Override
    public Boolean fastRegister(User user) {
        return userMapper.fastInsertUser(user);
    }

    /**
     * 检验用户权限
     *
     * @param user
     * @return true:鉴权通过  false：鉴权失败
     */
    @Override
    public Boolean verifyPermissions(User user) {
        int count;
        try {
            count = userMapper.verifyPermissions(user);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        if (count >= 1) {
            //表示当前用户在数据库中存在权限记录
            return true;
        }
        return false;
    }


    /**
     * 获取当前项目中可以被分配的用户成员们
     *
     * @param user
     * @param projectId
     * @return
     */
    @Override
    public Result getAssignableUsers(User user, String projectId) {
        //1.校验是否用权限查询
        Boolean aBoolean = verifyPermissions(user);
        if (aBoolean) {
            try {
                //2.有权限了进行查询 获取到满足条件的用户id
                //todo:查不出数据

                List<Long> allUserInProject = projectMapper.getAllUserInProject(projectId, user.getUid());
                //3.将满足条件的用户id去查询 user_info
                //todo:通过userid去查询user信息报错了
                //List<UserInfo> userInfos = userInfoMapper.selectBatchIds(allUserInProject);
                List<UserInfo> userInfos = userMapper.getUserInfoList(allUserInProject);
                //封装数据
                List<AssignableUserDto> list = new ArrayList<>();
                for (int i = 0; i < userInfos.size(); i++) {
                    AssignableUserDto assignableUserDto = new AssignableUserDto();
                    BeanUtils.copyProperties(userInfos.get(i), assignableUserDto);
                    //4.查询出当前用户的待办任务数
                    int undoTasks = taskMapper.countUndoTasks(userInfos.get(i).getUserId());
                    assignableUserDto.setProgressTasksNum(undoTasks);
                    list.add(assignableUserDto);
                }
                return Result.ok(list);
            } catch (BeansException e) {
                e.printStackTrace();
                return Result.fail("未知错误！");
            }


        }
        return Result.fail("没有权限！");
    }


    /**
     * 获取到当前用户id对应的用户的最高权限
     *
     * @param userId
     * @return
     */
    @Override
    public Result getUserRoles(Long userId) {
        int userRoles = userMapper.getUserRoles(userId);
        if (userRoles != 0) {
            return Result.ok(userRoles);
        }
        return Result.fail("用户并没有设置权限！");

    }

    /**
     * 用户上传头像存入user_info表中
     * 和minio中，并且返回user上传成功的图片的url给前端进行图片回显
     *
     * @return true上传成功   false上传不成功
     */
    @Override
    public Result uploadAvatar(MultipartFile multipartFile, HttpServletRequest request) {
        //1.检查参数
        if (multipartFile == null || multipartFile.getSize() == 0) {
            return Result.fail("上传文件为空！");
        }
        //2.上传图片到minIO中
        String fileName = VerificationCodeUtils.getCode(10, 1);
        //aa.jpg
        String originalFilename = multipartFile.getOriginalFilename();
        String postfix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileId = null;
        try {
            fileId = fileStorageService.uploadImgFile("", fileName + postfix, multipartFile.getInputStream());
            log.info("上传图片到MinIO中，fileId:{}", fileId);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("上传文件失败");
        }
        //3.将上传的头像保存到db中
        String token = request.getHeader("token");
        String userId = JWT.decode(token).getAudience().get(0);
        Long currentUserId = Long.valueOf(userId);
        boolean setUserImgUrl = userMapper.setUserImgUrl(currentUserId, fileId);

        if (setUserImgUrl) {
            //上传minio成功且保存db成功，则向前端返回图片url
            return Result.ok(fileId);
        }
        return Result.fail("上传文件失败！");
    }

    /**
     * 通过当前用户信息查db获取头像的url并返回前端显示
     *
     * @param userDto
     */
    @Override
    public void downloadAvatar(UserDto userDto) {
        //1.获取当前用户的主键
        //2.去userInfo表中查询到对应用户头像的url
        //3.根据url去minio中下载并返回字节流
    }

    /**
     * 提供给个人信息的修改接口，获取用户的所有信息
     * 包括：账号、姓名、邮箱、职位、部门、电话、等
     * 需要查询user_info、user_role_relation、user表
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public Result getUserAllInfo(Long userId) {
        try {
            UserAllInfo userAllInfo = new UserAllInfo();
            //0.获取用户电话、账号信息
            User byId = userMapper.getUserByUserId(userId);
            BeanUtils.copyProperties(byId, userAllInfo);

            //1.查询user_info表 获取用户的 真实姓名、头像url、邮箱、性别、个人简介
            UserInfo userInfo = userMapper.getUserInfo(byId);
            BeanUtils.copyProperties(userInfo, userAllInfo);
            //kinroy 2023.12.30这里没把图片url封装上
            String userImgUrl = userMapper.getUserImgUrl(userId);
            userAllInfo.setAvatar_image(userImgUrl);
            //2.查询tb_department表和 department_user_relation联表，获取用户的所在的部门名称
            //todo:联表查询出现问题了
            String departmentName = departmentMapper.getDepartmentNameByUserId(userId);
            userAllInfo.setDepName(departmentName);

            //3.查询出当前用户的职位序号
            int userRoles = userMapper.getUserRoles(userId);
            switch (userRoles) {
                case 1:
                    //部门领导
                    userAllInfo.setRoleName(departmentName + "-" + "部门领导");
                    break;
                case 2:
                    //项目组长
                    userAllInfo.setRoleName(departmentName + "-" + "项目组长");
                    break;
                case 3:
                    //普通员工
                    userAllInfo.setRoleName(departmentName + "-" + "员工");
                    break;
            }
            //4.封装好了将其发送给前端
            return Result.ok(userAllInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("获取用户信息失败！");
        }
    }

    /**
     * 用户个人信息修改
     * 主要修改两张表 user和user_Info
     *
     * @param userAllInfo
     * @return
     */
    @Override
    @Transactional
    public Result editUserAllInfo(UserAllInfo userAllInfo) {
        try {
            //邮箱校验
            if (!ReUtil.isMatch("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", userAllInfo.getEmail())) {
                throw new Exception();
            }
            // 电话号码验证
            String phoneNumber = "12345678901";
            if (!ReUtil.isMatch("^(1[3456789])\\d{9}$", userAllInfo.getPhone())) {
                throw new Exception();
            }
            //1.修改user表中的电话信息
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            User updateUser = new User();
            BeanUtils.copyProperties(userAllInfo, updateUser);
            wrapper.eq(userAllInfo.getUid() != 0, User::getUid, userAllInfo.getUid());
            boolean updateUserTable = update(updateUser, wrapper);

            //2.修改user_info表的数据
            LambdaQueryWrapper<UserInfo> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(userAllInfo.getUid() != 0, UserInfo::getUserId, userAllInfo.getUid());
            UserInfo updateUserInfo = new UserInfo();
            BeanUtils.copyProperties(userAllInfo, updateUserInfo);
            /*int updateUserInfoTable = userInfoMapper.update(updateUserInfo, wrapper1);*/

            //kinroy 2024.2.4 用户修改个人信息和管理员修改用户信息是同一个接口，但是管理员可以改其部门
            /*
             * 修改了用户的部门信息，则也会同时修改用户的职位
             * */
            //1.改职位
            String depName = userAllInfo.getDepName();
            String jobType = depName.substring(0, 4);
            updateUserInfo.setJobType(jobType);

            //2.去department_user_relation表中修改对应关系
            List<Department> departmentList = departmentMapper.getDepartmentList();
            for (Department department : departmentList) {
                if (department.getDepartmentName().equals(userAllInfo.getDepName())) {
                    departmentMapper.updateDepOfUser(userAllInfo.getUid(), department.getDepartmentId());
                    break;
                }
            }
            //最后再去修改一下user_info表
            int updateUserInfoTable = userInfoMapper.update(updateUserInfo, wrapper1);

            if (updateUserTable && (updateUserInfoTable != 0)) {
                return Result.ok(true);
            } else {
                return Result.fail("修改信息失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("修改信息失败!");
        }
    }

    /**
     * 获取用户头像的简单接口
     *
     * @param userId
     * @return
     */
    @Override
    public String getAvatar(Long userId) {
        return userMapper.getUserImgUrl(userId);
    }

    /**
     * 通过项目id获取当前项目的完成任务数top5的员工数据
     *
     * @param projectId
     * @return
     */
    @Override
    public Result getEmployeeRanking(String projectId, Long mangerUserId) {
        List<Long> userIdList = new ArrayList<>();
        List<Project> userManagerProjectList = projectMapper.getUserManagerProjectList(mangerUserId);
        //kinroy 2024.1.17 新增业务功能：前端默认先查出项目组长管理项目中的所有员工的总排名
        if (StrUtil.isBlank(projectId)) {
            //1.获取当前用户所管理的所有项目的list
            for (int i = 0; i < userManagerProjectList.size(); i++) {
                //把当前项目组长所管理的所有项目的组员id查出存入userIdList中
                List<Long> idList = projectService.getUserListByProjectId(userManagerProjectList.get(i).getProjectId());
                userIdList.addAll(idList);
            }
            //因为一个员工可能在多个项目中，需要对员工进行去重
            /*userIdList.stream().distinct();*/
            List<Long> collect = userIdList.stream().distinct().collect(Collectors.toList());
            userIdList = collect;
        } else {
            //1.通过项目id去查询当前项目的组员的用户id
            userIdList = projectService.getUserListByProjectId(projectId);
        }
        //2.封装排行榜展示数据dto
        PriorityQueue<RankingUserDto> rankingUserList = new PriorityQueue<>(new Comparator<RankingUserDto>() {
            @Override
            public int compare(RankingUserDto o1, RankingUserDto o2) {
                //重写一下compare方法，实现大顶堆
                //kinroy 2024.1.17 优化一下排序功能：如果两个员工的完成任务数相同，则比较绩效
                if (o2.getNumOfCompleted() - o1.getNumOfCompleted() == 0) {
                    //todo:比较绩效(未完成)
                    double v = o2.getPerformance() - o1.getPerformance();
                    if (v > 0) {
                        return 1;
                    } else if (v < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
                return o2.getNumOfCompleted() - o1.getNumOfCompleted();
            }
        });
        if (StrUtil.isBlank(projectId)) {
            //默认没选择任何项目的情况，需要去用用户id去查询各个项目中的任务完成数
            for (int i = 0; i < userManagerProjectList.size(); i++) {
                String projectName = userManagerProjectList.get(i).getProjectName();
                String projectIdInList = userManagerProjectList.get(i).getProjectId();
                for (int i1 = 0; i1 < userIdList.size(); i1++) {
                    //遍历这些员工在不同的project中的各种的完成任务数
                    RankingUserDto rankingUserDto = new RankingUserDto();
                    //0.获取用户id
                    Long userId = userIdList.get(i1);
                    rankingUserDto.setUid(userId);
                    //1.获取用户姓名
                    String userInfoName = userMapper.getUserInfoNameByUserId(userId);
                    rankingUserDto.setInfoName(userInfoName);
                    //2.获取用户在当前项目中完成的任务数
                    int doneTaskNum = taskMapper.countDoneTaskNumOfProjectByUserId(userId, projectIdInList);
                    rankingUserDto.setNumOfCompleted(doneTaskNum);
                    //3.设置项目名称
                    rankingUserDto.setProjectName(projectName);
                    //4.设置绩效
                    Double userPerformance = getUserPerformance(userId);
                    rankingUserDto.setPerformance(userPerformance);
                    //5.加入优先队列
                    rankingUserList.add(rankingUserDto);
                }
            }
        } else {
            //选中了某一个项目的情况
            for (int i = 0; i < userIdList.size(); i++) {
                RankingUserDto rankingUserDto = new RankingUserDto();
                //0.获取用户id
                Long userId = userIdList.get(i);
                rankingUserDto.setUid(userId);
                //1.获取用户姓名
                String userInfoName = userMapper.getUserInfoNameByUserId(userId);
                rankingUserDto.setInfoName(userInfoName);
                //2.获取用户在当前项目中完成的任务数
                int doneTaskNum = taskMapper.countDoneTaskNumOfProjectByUserId(userId, projectId);
                rankingUserDto.setNumOfCompleted(doneTaskNum);
                //3.设置项目名称
                Result projectNameById = projectService.getProjectNameById(projectId);
                String projectNameByIdData = (String) projectNameById.getData();
                rankingUserDto.setProjectName(projectNameByIdData);
                //4.设置绩效
                Double userPerformance = getUserPerformance(userId);
                rankingUserDto.setPerformance(userPerformance);
                //5.加入优先队列中
                rankingUserList.add(rankingUserDto);
            }
        }
        //3.从优先队列中取出数据5次，获取到top5的用户
        List<RankingUserDto> showData = new ArrayList<>();

        for (int i = 0; i <= 4; i++) {
            RankingUserDto poll = rankingUserList.poll();
            showData.add(poll);
        }
        if (showData.size() == 0) {
            return Result.fail("获取排行榜失败！");
        }
        return Result.ok(showData);
    }

    /**
     * 通过项目id获取当前项目的所有员工信息
     * 封装成 userAllInfo 这个dto的list返回给前端
     *
     * @param projectId
     * @return
     */
    @Override
    public Result getProjectEmployees(String projectId, User user) {
        //1.校验是否用权限查询
        Boolean aBoolean = verifyPermissions(user);
        List<UserAllInfo> userAllInfoList = new ArrayList<>();
        if (aBoolean) {
            //鉴权通过，查询并封装员工信息
            List<Long> allUserInProject = projectMapper.getAllUserInProject(projectId, user.getUid());
            for (int i = 0; i < allUserInProject.size(); i++) {
                Long userId = allUserInProject.get(i);
                UserAllInfo userAllInfo = new UserAllInfo();
                //0.获取用户电话、账号信息
                User byId = userMapper.getUserByUserId(userId);
                BeanUtils.copyProperties(byId, userAllInfo);

                //1.查询user_info表 获取用户的 真实姓名、头像url、邮箱、性别、个人简介
                UserInfo userInfo = userMapper.getUserInfo(byId);
                BeanUtils.copyProperties(userInfo, userAllInfo);
                //kinroy 2023.12.30这里没把图片url封装上
                String userImgUrl = userMapper.getUserImgUrl(userId);
                userAllInfo.setAvatar_image(userImgUrl);
                //2.查询tb_department表和 department_user_relation联表，获取用户的所在的部门名称
                //todo:联表查询出现问题了
                String departmentName = departmentMapper.getDepartmentNameByUserId(userId);
                userAllInfo.setDepName(departmentName);

                //3.查询出当前用户的职位序号
                int userRoles = userMapper.getUserRoles(userId);
                switch (userRoles) {
                    case 1:
                        //部门领导
                        userAllInfo.setRoleName(departmentName + "-" + "部门领导");
                        break;
                    case 2:
                        //项目组长
                        userAllInfo.setRoleName(departmentName + "-" + "项目组长");
                        break;
                    case 3:
                        //普通员工
                        userAllInfo.setRoleName(departmentName + "-" + "员工");
                        break;
                }
                userAllInfoList.add(userAllInfo);
            }
            //封装完成后返回给前端展示
            return Result.ok(userAllInfoList);


        }
        return Result.fail("没有权限！");
    }

    /**
     * 项目组员分配-获取可加入项目的所有用户
     * 加入项目的所有员工（指的是除了当前项目已有用户外的其他所有用户）
     *
     * @param projectId
     * @return
     */
    @Override
    public Result getCanAddedEmployees(String projectId) {
        //前端穿梭框展示的数据结构为 TransferItem（key，label，disable），在这里userId为key，lable为“姓名：XXX 职位：XXX”
        //1.获取当前项目的所有用户
        List<Long> userIdsFromProjectOnlyStaff = userMapper.getUserIdsFromProjectOnlyStaff(projectId);
        //2.获取所有的用户
        List<Long> allUserIds = userMapper.getAllUserIds();
        //3.在所有用户中去除当前项目的用户
        allUserIds.removeAll(userIdsFromProjectOnlyStaff);
        //4.封装成 TransferItem 数据返回前端展示
        List<TransferItem> transferItemList = new ArrayList<>();
        for (int i = 0; i < allUserIds.size(); i++) {
            Long userId = allUserIds.get(i);
            UserAllInfo userAllInfo = new UserAllInfo();
            //0.获取用户电话、账号信息
            User byId = userMapper.getUserByUserId(userId);
            BeanUtils.copyProperties(byId, userAllInfo);

            //1.查询user_info表 获取用户的 真实姓名、头像url、邮箱、性别、个人简介
            UserInfo userInfo = userMapper.getUserInfo(byId);
            BeanUtils.copyProperties(userInfo, userAllInfo);
            //kinroy 2023.12.30这里没把图片url封装上
            String userImgUrl = userMapper.getUserImgUrl(userId);
            userAllInfo.setAvatar_image(userImgUrl);
            //2.查询tb_department表和 department_user_relation联表，获取用户的所在的部门名称
            //todo:联表查询出现问题了
            String departmentName = departmentMapper.getDepartmentNameByUserId(userId);
            userAllInfo.setDepName(departmentName);

            //3.查询出当前用户的职位序号
            int userRoles = userMapper.getUserRoles(userId);
            //kinroy 2024.1.20 不能给项目组长和部门领导加入项目中
            if (userRoles != 3) {
                continue;
            } else {
                userAllInfo.setRoleName(departmentName + "-" + "员工");
                //封装TransferItem
                TransferItem transferItem = new TransferItem();
                transferItem.setKey(userAllInfo.getUid());
                transferItem.setLabel(userAllInfo.getInfoName() + " " + userAllInfo.getRoleName());
                transferItemList.add(transferItem);
            }
            /*switch (userRoles) {
                case 1:
                    //部门领导
                    userAllInfo.setRoleName(departmentName + "-" + "部门领导");
                    break;
                case 2:
                    //项目组长
                    userAllInfo.setRoleName(departmentName + "-" + "项目组长");
                    break;
                case 3:
                    //普通员工
                    userAllInfo.setRoleName(departmentName + "-" + "员工");
                    break;
            }

            //封装TransferItem
            TransferItem transferItem = new TransferItem();
            transferItem.setKey(userAllInfo.getUid());
            transferItem.setLabel(userAllInfo.getInfoName() + " " + userAllInfo.getRoleName());
            transferItemList.add(transferItem);*/
        }
        return Result.ok(transferItemList);
    }

    /**
     * 员工管理的条件查询
     * 根据选中的部门或者是否是非普通员工以及根据
     * userId进行条件查询显示table数据
     *
     * @param depName
     * @param userRole
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public Result getUserForManagerConditional(String depName, Integer userRole, Integer currentPage, Integer pageSize) {
        List<UserAllInfo> userAllInfoList = new ArrayList<>();
        //如果前端传来的userRole为4，则表示查询所有权限的用户
        if (userRole == 4) {
            List<User> allUserList = list();
            for (User user : allUserList) {
                UserAllInfo userAllInfo = new UserAllInfo();
                UserInfo userInfo = userMapper.getUserInfo(user);
                BeanUtils.copyProperties(userInfo, userAllInfo);
                BeanUtils.copyProperties(user, userAllInfo);
                //userAllInfo独有的两个成员变量：1.roleName  2.depName
                String departmentNameByUserId = departmentMapper.getDepartmentNameByUserId(user.getUid());
                userAllInfo.setDepName(departmentNameByUserId);
                String userRoleName = getUserRoleName(userMapper.getUserRoles(user.getUid()));
                userAllInfo.setRoleName(userRoleName);
                //userAllInfo封装完成，加入到返回数据的List中
                userAllInfoList.add(userAllInfo);
            }
        } else {
            //前端传来的userRole!=4,则表示有权限的条件查询
            List<Long> userIds = userMapper.getUserIdsSatisfyRole(userRole);
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(User::getUid, userIds);
            List<User> users = list(wrapper);
            for (User user : users) {
                UserAllInfo userAllInfo = new UserAllInfo();
                UserInfo userInfo = userMapper.getUserInfo(user);
                BeanUtils.copyProperties(userInfo, userAllInfo);
                BeanUtils.copyProperties(user, userAllInfo);
                //userAllInfo独有的两个成员变量：1.roleName  2.depName
                String departmentNameByUserId = departmentMapper.getDepartmentNameByUserId(user.getUid());
                userAllInfo.setDepName(departmentNameByUserId);
                String userRoleName = getUserRoleName(userMapper.getUserRoles(user.getUid()));
                userAllInfo.setRoleName(userRoleName);
                //userAllInfo封装完成，加入到返回数据的List中
                userAllInfoList.add(userAllInfo);
            }
        }
        //部门条件查询处理
        if (depName != null && depName != "") {
            //筛选出满足部门的条件的userAllInfo数据 使用stream流的方式
            List<UserAllInfo> collect = userAllInfoList.stream()
                    .filter(userAllInfo -> userAllInfo.getDepName() == depName)
                    .collect(Collectors.toList());
            userAllInfoList = collect;
        }

        //因为table展示的数据是通过查询多张表拼凑的数据，所有常规的分页api我们就不能调用了，需要自己写分页逻辑
        Map<String, Object> resultMap = new HashMap<>();
        int size = userAllInfoList.size();
        resultMap.put("totalData", size);
        Integer startIndex = pageSize * (currentPage - 1);

        if (startIndex > size) {
            resultMap.put("pageData", null);
            return Result.ok(resultMap);
        }
        //获取页面数据
        List<UserAllInfo> result = new ArrayList<>();

        for (int i = startIndex; i < (startIndex + pageSize); i++) {
            result.add(userAllInfoList.get(i));
            //当userAllInfoList中的数据无法充满一页时
            if ((i + 1) >= userAllInfoList.size()) {
                break;
            }
        }
        resultMap.put("pageData", result);
        return Result.ok(resultMap);
    }

    /**
     * 删除用户的所有信息（tb_user，user_info,user_role_relation,department_user_relation）
     * 还有project_user_relation
     * 若当前用户还有任务待办的，把任务进行挂起
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public Result delUserAllData(Long userId) {
        //根据userId去批量删除user的数据
        User selectUser = new User();
        selectUser.setUid(userId);
        UserInfo userInfo = userMapper.getUserInfo(selectUser);
        String imageUrl = userInfo.getAvatarImage();

        //1.删除minio中的用户头像数据
        fileStorageService.delete(imageUrl);
        //2.删除用户数据
        userMapper.delUserByUserId(userId);
        userMapper.delUserInfoByUserId(userId);
        userMapper.delUserDepInfoByUserId(userId);
        userMapper.delUserRoleInfoByUserId(userId);
        userMapper.delUserFormProjectByUserId(userId);

        //查询出当前用户的待办任务，并将其挂起，经办人变成项目组长，添加node节点记录
        List<Task> myTasks = taskMapper.getMyTasks(userId);
        if (myTasks.size() != 0) {
            for (Task task : myTasks) {
                //先修改状态和经办人，并更新tb_task中对应的数据，然后创建任务节点，
                Long createUserId = task.getCreateUserId();
                task.setCurrentTaskHandlerId(createUserId);
                task.setTaskStatus(TaskStatus.PENDING.getCode());
                //更新db
                taskMapper.updateById(task);
                //创建任务节点
                nodeService.createNode(task);
            }
        }
        //没有待办则可以直接删除完成了
        return Result.ok();
    }

    /**
     * 在员工管理模块的新增员工功能
     * 需要向tb_user,user_Info、user_role_relation、department_user_relation
     * 这些表中添加数据
     *
     * @param userAllInfo
     * @return
     */
    @Override
    @Transactional
    public Result addUser(UserAllInfo userAllInfo) {
        //1.直接调用以前写好的注册接口，但是要传入的是userDto，所以属性Copy一下
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userAllInfo, userDto);
        /*
         * 这个接口解决了tb_user表的所有字段，user_info表中的Introduction，Image
         * user_role_relation表中的员工角色
         * */
        registerService.register(userDto);
        /*user_info表还差字段（job_type,email,gender,info_name）
        department_user_relation 还没有绑定用户的部门信息
        * */
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getName, userAllInfo.getName());
        User reslut = getOne(wrapper);
        userAllInfo.setUid(reslut.getUid());
        List<Department> departmentList = departmentMapper.getDepartmentList();
        for (Department department : departmentList) {
            if (department.getDepartmentName().equals(userAllInfo.getDepName())) {
                departmentMapper.addDepForUser(userAllInfo.getUid(), department.getDepartmentId());
                break;
            }
        }
        this.editUserAllInfo(userAllInfo);
        return Result.ok();
    }

    /**
     * 根据UserId或者用户姓名进行条件查询
     *
     * @param selectValue
     * @return
     */
    @Override
    public Result selectUserConditional(String selectValue) {
        //1.判断传来的selectValue是userId还是用户姓名
        boolean matches = selectValue.matches("\\d+");

        if (matches) {
            //根据userId进行精确查询
            Long userId = Long.valueOf(selectValue);
            User user = new User();
            user.setUid(userId);
            UserAllInfo userAllInfo = new UserAllInfo();
            UserInfo userInfo = userMapper.getUserInfo(user);
            BeanUtils.copyProperties(userInfo, userAllInfo);
            BeanUtils.copyProperties(user, userAllInfo);
            //userAllInfo独有的两个成员变量：1.roleName  2.depName
            String departmentNameByUserId = departmentMapper.getDepartmentNameByUserId(user.getUid());
            userAllInfo.setDepName(departmentNameByUserId);
            String userRoleName = getUserRoleName(userMapper.getUserRoles(user.getUid()));
            userAllInfo.setRoleName(userRoleName);
            List<UserAllInfo> userAllInfoList = new ArrayList<>();
            userAllInfoList.add(userAllInfo);
            return Result.ok(userAllInfoList);
        } else {
            //根据用户姓名进行模糊查询
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.like(UserInfo::getInfoName, selectValue);
            List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
            List<UserAllInfo> userAllInfoList = new ArrayList<>();
            for (UserInfo userInfo : userInfos) {
                UserAllInfo userAllInfo = new UserAllInfo();
                BeanUtils.copyProperties(userInfo, userAllInfo);
                User user = userMapper.getUserByUserId(userInfo.getUserId());
                BeanUtils.copyProperties(user, userAllInfo);
                //userAllInfo独有的两个成员变量：1.roleName  2.depName
                String departmentNameByUserId = departmentMapper.getDepartmentNameByUserId(userInfo.getUserId());
                userAllInfo.setDepName(departmentNameByUserId);
                String userRoleName = getUserRoleName(userMapper.getUserRoles(userInfo.getUserId()));
                userAllInfo.setRoleName(userRoleName);
                userAllInfoList.add(userAllInfo);
            }
            return Result.ok(userAllInfoList);
        }
    }

    /**
     * 获取可被分配的项目组长数据
     * 除了当前项目组长外的其他项目组长 （查询user_role_relation和user的联表）
     *
     * @param currentProjectLeaderId
     * @return
     */
    @Override
    public Result getAllProjectLeader(Long currentProjectLeaderId) {

        List<UserAllInfo> userAllInfoList = new ArrayList<>();
        //鉴权通过，查询并封装员工信息
        /*List<Long> allUserInProject = projectMapper.getAllUserInProject(projectId, user.getUid());*/
        List<Long> allUserInProject = userMapper.getAllProjectLeaderIds(currentProjectLeaderId);
        for (int i = 0; i < allUserInProject.size(); i++) {
            Long userId = allUserInProject.get(i);
            UserAllInfo userAllInfo = new UserAllInfo();
            //0.获取用户电话、账号信息
            User byId = userMapper.getUserByUserId(userId);
            BeanUtils.copyProperties(byId, userAllInfo);

            //1.查询user_info表 获取用户的 真实姓名、头像url、邮箱、性别、个人简介
            UserInfo userInfo = userMapper.getUserInfo(byId);
            BeanUtils.copyProperties(userInfo, userAllInfo);
            //kinroy 2023.12.30这里没把图片url封装上
            String userImgUrl = userMapper.getUserImgUrl(userId);
            userAllInfo.setAvatar_image(userImgUrl);
            //2.查询tb_department表和 department_user_relation联表，获取用户的所在的部门名称
            //todo:联表查询出现问题了
            String departmentName = departmentMapper.getDepartmentNameByUserId(userId);
            userAllInfo.setDepName(departmentName);

            //3.查询出当前用户的职位序号
            int userRoles = userMapper.getUserRoles(userId);
            switch (userRoles) {
                case 1:
                    //部门领导
                    userAllInfo.setRoleName(departmentName + "-" + "部门领导");
                    break;
                case 2:
                    //项目组长
                    userAllInfo.setRoleName(departmentName + "-" + "项目组长");
                    break;
                case 3:
                    //普通员工
                    userAllInfo.setRoleName(departmentName + "-" + "员工");
                    break;
            }
            userAllInfoList.add(userAllInfo);
        }
        //封装完成后返回给前端展示
        return Result.ok(userAllInfoList);
    }


    /**
     * 获取当前用户权限
     * @param userId
     * @return
     */
    @Override
    public Result getUserRole(Long userId) {
        Integer userRoleNumByUserId = userMapper.getUserRoleNumByUserId(userId);
        return Result.ok(userRoleNumByUserId);
    }

    /**
     * 修改用户权限
     * @param updateUserId
     * @param currentUserId
     * @return
     */
    @Override
    public Result updateUserRole(Long updateUserId, Long currentUserId,Integer updateRoleNum) {
        //获取修改者的权限，修改者不能修改比自己高或者等于自己权限的用户
        Integer currentUserRole = userMapper.getUserRoleNumByUserId(currentUserId);
        Integer updateUserRole = userMapper.getUserRoleNumByUserId(updateUserId);
        if (currentUserRole>=updateUserRole){
            //1.无法修改权限比自己高的用户的角色
            return Result.fail("您没有修改当前用户的角色权限！");
        }else if (updateRoleNum<=currentUserRole){
            //2.无法修改用户的角色比自己的角色还高
            return Result.fail("您没有修改当前用户的角色权限！");
        }
        boolean flag = userMapper.updateUserRole(updateRoleNum, updateUserId);
        if (flag){
            return Result.ok();
        }else {
            return Result.fail("修改权限失败！");
        }

    }

    /**
     * 根据userId获取当前用户的日志和任务完成详细情况数据
     * @param userId
     * @return
     */
    @Override
    public Result getUserJobDetails(Long userId) {
        // 根据userId查询db获得对应数据存入数组中
        // 数组下标对应的数据映射为： 0-未完成任务 1-已完成任务 2-待提交日报 3-待提交周报
        Integer[] result=new Integer[4];
        // 未完成任务数
        int undoTaskNum = taskMapper.countUndoTasks(userId);
        result[0]=undoTaskNum;
        // 已完成任务数
        int completedTasksNum = taskMapper.countCompletedTasks(userId);
        result[1]=completedTasksNum;
        //待提交日报数
        result[2]=noteService.getUnPublishNoteNumByType(NoteType.Daily.getCode(),userId);
        //待提交周报数
        result[3]=noteService.getUnPublishNoteNumByType(NoteType.Weekly.getCode(),userId);
        return Result.ok(result);
    }

    /**
     * 根据userRoleNum获取相应的RoleName字符串
     *
     * @param userRoleNum
     * @return
     */
    public String getUserRoleName(int userRoleNum) {
        switch (userRoleNum) {
            case 1:
                return "部门领导";
            case 2:
                return "项目组长";
            case 3:
                return "普通员工";
            default:
                return "暂无";
        }
    }


    /**
     * 根据userId 获取相应用户的绩效分数
     *
     * @param userId
     * @return
     */
    public Double getUserPerformance(Long userId) {
        if (userId == 0) {
            return null;
        }
        int completedTasks = taskMapper.countCompletedTasks(userId);
        int allTasks = taskMapper.countAllTasksFormCurrentUser(userId);
        double performance = 0;
        try {
            if (completedTasks == 0 || allTasks == 0) {
                return performance;
            }
            performance = (double) completedTasks / (double) allTasks;
        } catch (Exception e) {
            e.printStackTrace();
            return Double.valueOf(performance);
        }
        // 创建DecimalFormat对象，指定格式
        DecimalFormat decimalFormat = new DecimalFormat("#.###");

        // 使用format方法将double值格式化为字符串
        String formattedValue = decimalFormat.format(performance);
        return Double.valueOf(formattedValue);
    }

}
